A code data-block is the run-time representation of a "component". A component is a connected portion of a program's flow graph that is compiled as a single unit, and it contains code for many functions. Some of these functions are callable from outside of the component, and these are termed "entry points".
Each entry point has an associated user-visible function data-block (of type function). The full call convention provides for calling an entry point specified by a function object.
Although all of the function data-blocks for a component's entry points appear to the user as distinct objects, the system keeps all of the code in a single code data-block. The user-visible function object is actually a pointer into the middle of a code data-block. This allows any control transfer within a component to be done using a relative branch.
Besides a function object, there are other kinds of references into the middle of a code data-block. Control transfer into a function also occurs at the return-PC for a call. The system represents a return-PC somewhat similarly to a function, so GC can also recognize a return-PC as a reference to a code data-block. This representation is known as a Lisp Return Address (LRA).
It is incorrect to think of a code data-block as a concatenation of "function data-blocks". Code for a function is not emitted in any particular order with respect to that function's function-header (if any). The code following a function-header may only be a branch to some other location where the function's "real" definition is.
The following are the three kinds of pointers to code data-blocks:
Information about functions that is only useful for entry points is kept in some descriptors following the function's self-pointer descriptor. All of these together with the function's header-word are known as the "function header". GC must be able to locate the function header. We provide for this by chaining together the function headers in a NIL terminated list kept in a known slot in the code data-block.
A code data-block has the following format:
A --> **************************************************************** | Header-Word count (24 bits) | Code-Type (8 bits) | ---------------------------------------------------------------- | Number of code words (fixnum tag) | ---------------------------------------------------------------- | Pointer to first function header (other-pointer tag) | ---------------------------------------------------------------- | Debug information (structure tag) | ---------------------------------------------------------------- | First constant (a descriptor) | ---------------------------------------------------------------- | ... | ---------------------------------------------------------------- | Last constant (and last word of code header) | ---------------------------------------------------------------- | Some instructions (non-descriptor) | ---------------------------------------------------------------- | (pad to dual-word boundary if necessary) | B --> **************************************************************** | Word offset from code header (24) | Return-PC-Type (8) | ---------------------------------------------------------------- | First instruction after return | ---------------------------------------------------------------- | ... more code and LRA header-words | ---------------------------------------------------------------- | (pad to dual-word boundary if necessary) | C --> **************************************************************** | Offset from code header (24) | Function-Header-Type (8) | ---------------------------------------------------------------- | Self-pointer back to previous word (with other-pointer tag) | ---------------------------------------------------------------- | Pointer to next function (other-pointer low-tag) or NIL | ---------------------------------------------------------------- | Function name (a string or a symbol) | ---------------------------------------------------------------- | Function debug arglist (a string) | ---------------------------------------------------------------- | Function type (a list-style function type specifier) | ---------------------------------------------------------------- | Start of instructions for function (non-descriptor) | ---------------------------------------------------------------- | More function headers and instructions and return PCs, | | until we reach the total size of header-words + code | | words. | ----------------------------------------------------------------
The following are detailed slot descriptions:
(function (fixnum fixnum fixnum) fixnum)or
(function (string &key (:start unsigned-byte)) string)This information is intended for machine readablilty, such as by the compiler.